package com.linjiang.proxy;

import com.linjiang.common.Invocation;
import com.linjiang.common.URL;
import com.linjiang.loadbalance.Loadbalance;
import com.linjiang.protocol.HttpClient;
import com.linjiang.register.MapRemoteRegister;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

public class ProxyFactory {
    public static <T> T getProxy(Class interfaceClass){
        //生成代理对象
        Object proxyInstance = Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{interfaceClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //实现mock
                String mock = System.getProperty("mock");
                if ((mock != null && mock.startsWith("return:"))){
                    String result = mock.replace("return:", "");
                    return result;
                }

                //代理逻辑
                //指定调用的接口名、方法、方法参数
                String methodName = method.getName();
                String version = "1.0";
                Class[] parameterType = method.getParameterTypes();
                Invocation invocation = new Invocation(interfaceClass.getName(), version, methodName, parameterType, args);

                //根据接口名获取服务的节点信息列表 -- 服务发现
                List<URL> urlList = MapRemoteRegister.get(interfaceClass.getName());

                //负载均衡
                Loadbalance loadbalance = new Loadbalance();

                //服务调用
                String result = null;
                int max = 3;
                while (max > 0){
                    URL url = null;
                    try {
                        //随机获取某个节点
                        url = loadbalance.random(urlList);
                        HttpClient httpClient = new HttpClient();
                        result = httpClient.send(url.getHostName(), url.getPort(), invocation);
                        break;
                    }catch (Exception e){
                        //排除掉当前节点
                        urlList.remove(url);
                        //服务重试
                        max --;
                        if (max == 0){
                            //可以实现容错逻辑
                            return "报错了";
                        }
                    }
                }
                //返回请求结果
                return result;
            }
        });
        return (T) proxyInstance;
    }
}
